package com.pig4cloud.pigx.user.util;

import java.math.BigInteger;
import java.util.Arrays;


import org.web3j.crypto.ECDSASignature;
import org.web3j.crypto.Hash;
import org.web3j.crypto.Keys;
import org.web3j.crypto.Sign;
import org.web3j.crypto.Sign.SignatureData;
import org.web3j.utils.Numeric;

/**
 * Web3j签名验签
 *
 * @date:2022/8/13
 */
public class Web3jSignatureValid {

	public static final String PERSONAL_MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n";

	/**
	 *
	 * @param address 授权钱包地址
	 * @param signature 签名后数据
	 * @param message 签名原文
	 * @return
	 */
	public static boolean isSignatureValid(final String address, final String signature, final String message) {
		String prefix = PERSONAL_MESSAGE_PREFIX + message.length();
		byte[] msgHash = Hash.sha3((prefix + message).getBytes());

		byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
		byte v = signatureBytes[64];
		if (v < 27) {
			v += 27;
		}

		SignatureData sd =
				new SignatureData(
						v,
						(byte[]) Arrays.copyOfRange(signatureBytes, 0, 32),
						(byte[]) Arrays.copyOfRange(signatureBytes, 32, 64));

		String addressRecovered = null;
		boolean match = false;

		// Iterate for each possible key to recover
		for (int i = 0; i < 4; i++) {
			BigInteger publicKey =
					Sign.recoverFromSignature(
							(byte) i,
							new ECDSASignature(
									new BigInteger(1, sd.getR()), new BigInteger(1, sd.getS())),
							msgHash);

			if (publicKey != null) {
				addressRecovered = "0x" + Keys.getAddress(publicKey);

				if (addressRecovered.toLowerCase().equals(address.toLowerCase())) {
					match = true;
					break;
				}
			}
		}
		return  match;
	}

}
